import "reflect-metadata";
import dayjs from "dayjs";
import { Router } from "../autox/router";
import { clickButton, getCurrentViewNode } from "../utils";
import { getHttpPost } from "../tokens";
import * as tokens from '../tokens'
import * as utils from '../utils'
import { mainRegister } from "../autox/bootstrap/mainRegister";
import { httpGetAsync } from "../autox/http";
mainRegister()
declare const Intent: any;
toast(`启动成功`)
const floatyWindow = tokens.getFloatyWindow()
floatyWindow.render(`<vertical id="main">
    <horizontal padding="15 5 15 5" bg="#000000">
        <text layout_weight="1" id="title" textSize="12" gravity="left" text="" textColor="#FFFFFF"/>
    </horizontal>
    <horizontal padding="15 5 15 5" bg="#000000">
        <text layout_weight="1" id="red" textSize="30" gravity="left" text="0" textColor="#e96900"/>
        <text layout_weight="1" id="red_count_v" textSize="12" gravity="left" text="红包" textColor="#FFFFFF"/>
    </horizontal>
    <horizontal padding="15 5 15 5" bg="#000000">
        <text layout_weight="1" id="money" textSize="30" gravity="left" text="0" textColor="#e96900"/>
        <text layout_weight="1" textSize="12" gravity="left" text="币" textColor="#FFFFFF"/>
    </horizontal>
    <horizontal padding="15 5 15 5" bg="#000000">
        <text layout_weight="1" id="mood" textSize="30" gravity="left" text="0" textColor="#e96900"/>
        <text layout_weight="1" textSize="12" gravity="left" text="心情" textColor="#FFFFFF"/>
    </horizontal>
    <horizontal padding="15 5 15 5" bg="#000000">
        <text layout_weight="1" id="tip" textSize="12" gravity="left" text="" textColor="#FFFFFF"/>
    </horizontal>
</vertical>`)
log(`开始任务...`);
const uuid = tokens.getDeviceUuid()
const username = tokens.getDeviceName()
const httpGet = tokens.getHttpGet()
const httpPost = tokens.getHttpPost();
const updateFlotyWindow = () => httpGet(`mine`, { uuid: uuid }).then(res => {
    const isLeader = !(res.type === 'worker');
    ui.run(() => {
        if (res) {
            floatyWindow.window.red.setText(`${res.red}`)
            floatyWindow.window.money.setText(`${res.money}`)
            floatyWindow.window.mood.setText(`${res.mood}`)
            if (isLeader) {
                floatyWindow.window.title.setText(`找找找大红包...`)
            } else {
                if (res.status === `0`) {
                    floatyWindow.window.title.setText(`休息中...`)
                } else {
                    floatyWindow.window.title.setText(`抢包中...`)
                }
            }
        }
    })
    return { ...res, isLeader };
}).catch(e => {
    console.error(`更新窗口失败：`, e)
    return {}
});

let i = 0;
async function run(router: Router) {
    sleep(1000)
    const nodes = utils.getCurrentViewNodes(() => selector().filter(it => {
        const text = it.text()
        if (!text) return false;
        if (text === '复制连接') {
            return true;
        }
        if (text.includes('立即关注')) {
            return true;
        }
        if (text === '分享到') {
            return true;
        }
        if (text === '分享至') {
            return true;
        }
        return false;
    }))
    if (nodes.length > 0) {
        sleep(2000)
        back();
    }
    // 红心
    const roomAndRedInfo = getRoomAndRedInfo()
    if (!roomAndRedInfo) {
        throw new Error(`房间无红包`)
    }
    if (!roomAndRedInfo.redPackets) {
        throw new Error(`房间无红包`)
    }
    if (roomAndRedInfo.redPackets.length <= 0) {
        throw new Error(`房间无红包`)
    }
    const second = utils.toSecond(roomAndRedInfo.live_red_packet_status_text?.text)
    if (second < 30) {
        throw new Error(`时间来不及了`)
    }
    const openTime = roomAndRedInfo.open_time.format('YYYY-MM-DD HH:mm:ss')
    let count = 0;
    const hasSuccess = roomAndRedInfo.redPackets.some(it => {
        if (it.second_line_text_view?.text) {
            const text = it.__text;
            if (it.live_sec_kill_red_packet_pop_prepare_reward_kcoin_view) {
                count = parseInt(it.live_sec_kill_red_packet_pop_prepare_reward_kcoin_view?.text)
                return false;
            }
            if (text.includes(`开奖时需要留在直播间`)) {
                if (it.red_packet_cover_reward_usual_count) {
                    count = parseInt(it.red_packet_cover_reward_usual_count?.text)
                }
                return true;
            }
            if (text.includes(`在评论区发送口令，即可参与抢红包`)) {
                if (it.red_packet_cover_reward_usual_count) {
                    count = parseInt(it.red_packet_cover_reward_usual_count?.text)
                }
                return true;
            }
            if (text.includes(`开奖前留在直播间，更容易抢到`)) {
                console.log(it)
                return true;
            }
            if (text.includes(`加入主播粉丝团，即可参与抢红包`)) {
                return false;
            }
            // 在评论区发送口令，即可参与抢红包
        }
        return false;
    });
    if (!hasSuccess) throw new Error(`没有符合条件的包`)
    router.home();
    sleep(3000)
    const link = await getRoomLink(router)
    router.home();
    const username = tokens.getDeviceName()
    const uuid = tokens.getDeviceUuid()
    const online = parseInt(roomAndRedInfo.live_audience_count_text?.text || `0`)
    const httpPost = getHttpPost()
    await httpPost('addRedPkg', {
        ...link || {},
        username,
        uuid,
        time: new Date().getTime(),
        hasSuccess: hasSuccess,
        pkg: `com.smile.gifmaker`,
        openTime,
        count,
        online
    }).catch(e => {
        console.error(`addRedPkg error`, e)
    })
    sleep(3000)
}
async function bootstrap() {
    const { isLeader, status } = await updateFlotyWindow()
    if (isLeader) {
        if (i % 1000 === 0) {
            openKsLive()
        }
        i += 1;
        sleep(random(8000, 9000))
        // 获取房间信息
        const router = new Router()
        await run(router).catch(e => {
            console.error(e)
        }).finally(() => {
            router.home();
            sleep(random(2000, 3000))
            // 检查是否是直播间
            if (currentActivity() !== 'com.yxcorp.gifshow.HomeActivity') {
                utils.swipeUp()
            } else {
                openKsLive()
            }
        })
    } else {
        sleep(1000 * 10)
    }
}
const handler = async (payload) => {
    const now_time = dayjs().toDate().getTime();
    home();
    const open_date = dayjs(payload.open_date).add(30, 'second').toDate().getTime();
    const task = threads.start(async () => {
        // 停止其他脚本
        try {
            // 更新状态
            toastLog(`去抢红包-${payload.id}`)
            const { id, schema } = await httpPost('joinRedPacket', {
                uuid: uuid,
                username: username,
                id: payload.id
            }).catch(e => {
                console.error(e)
                return {}
            });
            if (!id) return;
            ui.run(() => {
                floatyWindow.window.title.setText(`正在抢包...`)
            });
            let count = 0;
            try {
                count = await joinRedActivity(payload, id, schema)
                if (count > 0) {
                    await updateFlotyWindow();
                }
                toast(`抢到了 ${count} 个币`)
            } catch (e) {
                console.error(`参加抢红包活动出错`, e)
            } finally {
                await httpPost(`updateRedPacket`, {
                    id,
                    count: count || 0
                }).catch(e => console.error(`updateRedPacket`, e));
            }
        } catch (e) {
            console.error(e)
        } finally {
            home()
        }
    });
    task.join(open_date - now_time);
    task.interrupt();
    home();
    return true;
}
// 抢红包钩子
async function joinRedActivity(payload: any, id: number, schema: string) {
    // 去哪个直播间
    const link: string = payload.link;
    const [preSchema, preLink] = link.split('://')
    const { origin_url } = payload;
    if (origin_url) {
        setClip(origin_url)
        app.launchPackage(schema === 'kwai' ? 'com.smile.gifmaker' : 'com.kuaishou.nebula')
        textContains('进入直播间').waitFor()
        sleep(random(2000, 3000))
        utils.clickButtonOrRect(textContains('进入直播间').findOne())
        sleep(random(1000 * 15, 1000 * 18))
    } else {
        toast(`room link is ${schema}://${preLink}`)
        toLivePlayPage(`${schema}://${preLink}`)
    }

    // 去哪个直播间
    toastLog(`检查直播间状态`)
    let live_red_packet_status_text = utils.getCurrentViewNodeUntil(() => selector().idMatches(/.+(live_red_packet_status_text|live_activity_red_packet_display_text_view)/), 8000)
    if (!live_red_packet_status_text) {
        back()
    }
    live_red_packet_status_text = utils.getCurrentViewNodeUntil(() => selector().idMatches(/.+(live_red_packet_status_text|live_activity_red_packet_display_text_view)/), 8000)
    if (!live_red_packet_status_text) {
        return 0;
    }
    toastLog(`直播间状态正常`)
    sleep(3000)
    utils.clickButton(live_red_packet_status_text)
    // 参与红包
    let actionView = utils.getCurrentViewNodeUntil(() => selector().idMatches(/.+(live_condition_leee_button_text|action_view)/), 8000)
    if (!actionView) {
        actionView = utils.getCurrentViewNodeUntil(() => selector().idMatches(/.+(live_condition_leee_button_text|action_view)/), 8000)
    }
    if (!actionView) {
        toastLog(`没有找到参与入口...`);
        return 0;
    }
    const text = actionView.text();
    toastLog(`成功找到参与按钮`);
    let isSkip = false;
    if (/.+后开奖/.test(text)) {
        toastLog(`已参与、等待开奖....`)
        isSkip = true;
    }
    let desc = utils.getCurrentViewNodeUntil(() => selector().idMatches(/.+(second_line_text_view)/), 5000)?.text() || '';
    toastLog(`活动要求:${desc}`)
    if (!isSkip) {
        if (desc === '开奖时需要留在直播间') {
            sleep(2000)
            utils.clickButton(actionView)
        }
        else if (desc.includes('发送口令')) {
            sleep(2000)
            utils.clickButton(actionView)
            sleep(3000)
            const sendBtn = utils.getCurrentViewNodeUntil(() => selector().textContains('发送'), 5000)
            if (sendBtn) {
                toastLog(`点击发送评论`)
                utils.clickButtonOrRect(sendBtn)
                sleep(2000)
                utils.clickButton(utils.getCurrentViewNodeUntil(() => selector().id('live_red_packet_status_text'), 5000))
            } else {
                toastLog(`没有找到发送按钮`)
                utils.clickButtonOrRect(utils.getCurrentViewNodeUntil(() => selector().textContains('发送'), 5000))
            }
        }
        else if (desc.includes('粉丝团')) {
            return 0;
        } else {
            toast(`啥也没做`)
            return 0;
        }
        sleep(1000)
    }
    toastLog(`参与成功,等待开奖....`)
    let getText = () => utils.getCurrentViewNodes(() => selector().filter(it => {
        const text = it.text()
        if (!text) return false;
        if (text.length > 3) return true;
        return false;
    })).map(it => it.text()).join(';');
    let texts = getText();
    toastLog(texts)
    let isStop = isRedResult(texts)
    while (!isStop) {
        texts = getText()
        toast(texts)
        isStop = isRedResult(texts)
        sleep(1000)
    }
    toast(`----------${texts}------------`)
    if (texts.includes('仅需1快币')) {
        const redPacketCoverRewardUsualCount = getCurrentViewNode(() => selector().id('red_packet_cover_reward_usual_count'))
        let count: number = 0;
        if (redPacketCoverRewardUsualCount) {
            count = parseInt(redPacketCoverRewardUsualCount.text());
            toastLog(`抢到${count}个币`)
            sleep(2000)
            toastLog(`抢到${count}个币`)
            sleep(2000)
            toastLog(`抢到${count}个币`)
            sleep(2000)
            return count;
        }
    }
    return 0;
}

function isRedResult(text: string) {
    return /仅需.快币|手慢了|红包溜走了|未中奖|任务失败|主播礼物/.test(text)
}

function openSetting(packageName: string) {
    // 创建意图对象
    const intent = app.intent({
        action: "android.settings.APPLICATION_DETAILS_SETTINGS",
        data: "package:" + packageName
    });
    // 启动应用设置页面
    app.startActivity(intent);
}
function killApp(packageName: string) {
    openSetting(packageName)
    sleep(2000)
    const stopNode = utils.getCurrentViewNodeUntil(() => selector().textMatches(/.*(强行|停止|结束).{0,3}/))
    if (stopNode) {
        clickButton(stopNode)
        sleep(2000)
        const stopElement = utils.getCurrentViewNodeUntil(() => selector().textMatches(/(确[定认]|(强行|停止|结束).{0,3})/))
        if (!stopElement) {
            toastLog(`应用关闭失败`)
        }
        if (stopElement) {
            clickButton(stopElement)
            sleep(2000)
        }
    }
    back()
    sleep(2000)
}
function clickShareAndCopy(router: Router) {
    if (clickButton(getCurrentViewNode(() => selector().id("live_bottom_bar_single_icon_container")))) {
        router.push('CLICK_SHARE_BUTTON')
        sleep(3000);
        if (!utils.clickButton(getCurrentViewNode(() => selector().id("live_bottom_bar_item_title_text_view").text(`分享`)))) {
            sleep(3000);
            router.back();
            return;
        }
        sleep(1000);
        if (!clickButton(getCurrentViewNode(() => selector().text(`复制链接`)))) {
            sleep(3000);
            router.back();
            return;
        }
        router.pop()
        sleep(3000);
        return;
    }
}
function toLivePlayPage(link: string, signal: boolean = true) {
    let flag: any = signal ? Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK : Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
    const uri = link;
    const intent = app.intent({
        action: "android.intent.action.VIEW",
        data: uri,
        flags: flag
    });
    context.startActivity(intent);
}
async function getRealLink(link: string) {
    const response = httpGetAsync(link)
    const url = response?.url.toString() as string;
    const [path, query] = url.split(`?`)
    const res = path.match(/fw\/live\/(.*)/)
    if (res && res.length > 0) {
        const [, ksid] = res;
        const params: any = {}
        query.split('&').map(key => {
            const [name, value] = key.split('=');
            params[name] = value;
        });
        const liveStreamId = params.shareObjectId
        const uri = `kwai://live/play/${liveStreamId}`;
        return { link: uri, userId: params.userId, ksid, originUrl: link };
    }
}
declare const getClip: any;
async function parseLink() {
    const link = getClip()
    if (link) {
        const res = link.match(/(http.*?) (.*?)的直播/)
        if (res && res.length > 0) {
            const link = res[1]
            const name = res[2]
            const shareLink = await getRealLink(link)
            return {
                name,
                originLink: link,
                ...shareLink,
            }
        }
    }
}
async function getRoomLink(router: Router) {
    clickShareAndCopy(router)
    sleep(random(500, 800))
    return await parseLink()
}
const LIVE_ROOM_TEXT_IDS: string[] = [
    'com.smile.gifmaker:id/text',
    'com.smile.gifmaker:id/live_name_text',
    'com.smile.gifmaker:id/live_audience_count_text',
    'com.smile.gifmaker:id/live_hourly_rank_content_view',
    'com.smile.gifmaker:id/live_side_bar_pendant_text_view',
    'com.smile.gifmaker:id/live_red_packet_status_text',
    'com.smile.gifmaker:id/live_red_packet_count',
    'com.smile.gifmaker:id/live_top_right_common_pendant_count_down',
    'com.smile.gifmaker:id/live_multi_chat_user_name',
    'com.smile.gifmaker:id/live_multi_chat_gift_text',
    'com.smile.gifmaker:id/title',
    'com.smile.gifmaker:id/subtitle_number',
    'com.smile.gifmaker:id/subtitle',
    'com.smile.gifmaker:id/action_button',
    'com.smile.gifmaker:id/live_activity_red_packet_count_text_view',
    'com.smile.gifmaker:id/live_activity_red_packet_display_text_view',
    'com.smile.gifmaker:id/live_interact_programme_title_text_view',
    'com.smile.gifmaker:id/live_interact_programme_pendant_programme_item_text',
    'com.smile.gifmaker:id/live_interact_programme_pendant_body_btn_text',
    'com.smile.gifmaker:id/live_follow_text',
    'com.smile.gifmaker:id/live_wish_list_name_text_view',
    'com.smile.gifmaker:id/live_wish_list_destination_text_view',
    'com.smile.gifmaker:id/live_gift_slot_username',
    'com.smile.gifmaker:id/live_gift_slot_gift_des',
    'com.smile.gifmaker:id/live_gift_slot_combo_count',
    'com.smile.gifmaker:id/content_text_view',
    'com.smile.gifmaker:id/live_multi_pk_user_tag',
    'com.smile.gifmaker:id/live_multi_pk_user_name',
    'com.smile.gifmaker:id/live_multi_pk_score_grade',
    'com.smile.gifmaker:id/live_multi_pk_left_score_text_view',
    'com.smile.gifmaker:id/live_multi_pk_right_score_text_view',
    'com.smile.gifmaker:id/live_multi_pk_count_down_time',
    'com.smile.gifmaker:id/live_player_bottom_quality_button'
]

const LIVE_RED_PACKET_TEXT_IDS: string[] = [
    'com.smile.gifmaker:id/common_red_packet_pop_prepare_reward_desc_view',
    'com.smile.gifmaker:id/live_condition_leee_button_text',
    'com.smile.gifmaker:id/live_red_packet_fling_tips',
    'com.smile.gifmaker:id/red_packet_cover_reward_usual_count',
    'com.smile.gifmaker:id/red_packet_cover_reward_usual_unit',
    'com.smile.gifmaker:id/prepare_reward_password_text_view',
    'com.smile.gifmaker:id/second_line_text_view',
    'com.smile.gifmaker:id/title_text_view',
    'com.smile.gifmaker:id/progress_text_view',
    'com.smile.gifmaker:id/red_packet_cover_reward_usual_count',
    'com.smile.gifmaker:id/red_packet_cover_reward_usual_unit',
    'com.smile.gifmaker:id/first_line_text_view',
    'com.smile.gifmaker:id/first_line_text_view',
    'com.smile.gifmaker:id/red_packet_pop_prepare_source_desc_view',
    'com.smile.gifmaker:id/live_sec_kill_red_packet_pop_prepare_reward_kcoin_view',
    'com.smile.gifmaker:id/live_sec_kill_prepare_reward_desc_text_view',
    'com.smile.gifmaker:id/count_down_text_view',
    'com.smile.gifmaker:id/tips_text_view',
];
function getLiveRoomInfo() {
    const nodes = utils.getCurrentViewNodes(() => selector().textMatches(/.{0,30}/))
    const open_time = dayjs()
    const room: any = {
        __text: ``,
        open_time: open_time
    }
    nodes.map(node => {
        const id = node.id();
        const text = node.text();
        room.__text += `${text} `;
        if (LIVE_ROOM_TEXT_IDS.includes(id)) {
            const [pkg, name] = id.split('/')
            const val = { text: node.text(), node }
            room[name] = val
        }
    });
    return room;
}
function roomGroupBy(depth: number = 2, node: UiObject | undefined): string | undefined {
    if (!node) return;
    const parent = node.parent();
    if (!parent) return;
    if (parent.className() === `androidx.viewpager.widget.ViewPager`) {
        if (node.className() === 'android.widget.FrameLayout' && node.depth() === 2) {
            const bounds = node.bounds()
            return `${bounds.left}_${bounds.right}`
        }
    }
    return roomGroupBy(depth, parent)
}
function getRoomInfoNodeGroupBy() {
    const nodes = utils.getCurrentViewNodes(() => selector().textMatches(/.{1,30}/))
    const list: Map<string, Set<UiObject>> = new Map();
    nodes.map(node => {
        const parent = roomGroupBy(2, node)
        if (parent) {
            const item = list.get(parent) || new Set()
            item.add(node)
            list.set(parent, item)
        }
    })
    return list;
}
function getRedPacketInfo() {
    const nodes = getRoomInfoNodeGroupBy();
    const rooms: any[] = [];
    nodes.forEach(list => {
        const room: any = {
            __text: ``
        }
        list.forEach(node => {
            const id = node.id();
            const text = node.text();
            room.__text += `${text} `;
            if (LIVE_RED_PACKET_TEXT_IDS.includes(id)) {
                const [pkg, name] = id.split('/')
                const val = { text: node.text(), node }
                room[name] = val
            } else {
                log(`${id}:${text}`)
            }
        })
        if (Object.keys(room).length > 1) {
            rooms.push(room)
        }
    })
    return rooms;
}
function getRoomAndRedInfo() {
    const room = getLiveRoomInfo();
    if (room.live_red_packet_status_text) {
        if (room.live_red_packet_status_text.text === '进行中') {
            log(`本房间暂无红包，请稍后再来检查....`)
            return;
        }
        const second = utils.toSecond(room.live_red_packet_status_text.text)
        log(`距离开奖还有：${second}s`)
        if (second > 0) {
            room.open_time = room.open_time.add(second, 'second');
            if (!utils.clickButton(room.live_red_packet_status_text.node)) {
                log(`点击红包开奖文字信息失败....`)
                return;
            }
            log(`获取房间内红包信息...`)
            sleep(1000)
            const redPackets = getRedPacketInfo()
            room.redPackets = redPackets;
            if (!utils.clickButton(utils.getCurrentViewNode(() => selector().idMatches(/.{0,15}close.{0,8}/)))) {
                log(`关闭按钮点击失败....`)
                back();
            }
            // 获取分享连接
            return room;
        }
        return;
    }
    log(`本房间暂无红包，请稍后再来检查....`)
    return;
}
function openKsLive(signal: boolean = true) {
    let flag: any = signal ? Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK : Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
    const uri = `kwai://liveaggregatesquare`
    const intent = app.intent({
        action: "android.intent.action.VIEW",
        data: uri,
        flags: flag
    });
    context.startActivity(intent);
}




const interval = setInterval(() => { }, 1000)

events.broadcast.on('RED_PACKET_JOIN', handler);

const watch = threads.start(() => {
    while (true) {
        const nodes = utils.getCurrentViewNodes(() => selector().filter(it => {
            const text = it.text()
            if (!text) return false;
            if (text === '我知道了') {
                return true;
            }
            if (text === '领取并使用') {
                return true;
            }
            if (text === '退出直播间') {
                return true;
            }
            if (text === '关注并领取') {
                return true;
            }
            if (text === '去填写') {
                return true;
            }
            if (text.includes('试试手气')) {
                return true;
            }
            if (text === '立即抢红包') {
                return true;
            }
            if (text === '支持红队') {
                return true;
            }
            if (text.includes('开启快手时')) {
                return true;
            }
            if (text === '版本更新') {
                return true;
            }
            if (text === '关注主播') {
                return true;
            }
            if (text === '直播已结束') {
                return true;
            }
            if (text === '放弃机会') {
                return true;
            }
            if (text === '去关注') {
                return true;
            }
            if (text === '退出') {
                return true;
            }
            if (text.includes('后领优惠券')) {
                return true;
            }
            if (text === `直播已结束`) {
                return true;
            }
            if (text === `点击查看回放`) {
                return true;
            }
            return false;
        }))
        if (nodes.length > 0) {
            back();
        }
        sleep(1000)
    }
})
const task = threads.start(async () => {
    while (true) {
        await bootstrap().catch(e => {
            console.error(e)
            sleep(10 * 1000)
        }).finally(() => {
            // toastLog(`本轮任务完成,即将进入下一轮`)
        });
    }
})

events.on('exit', () => {
    if (watch && watch.isAlive()) {
        watch.interrupt()
    }
    if (task && task.isAlive()) {
        task.interrupt()
    }
    clearInterval(interval)
    events.broadcast.removeListener('RED_PACKET_JOIN', handler)
})
